package main

import (
	"reflect"
	"strings"
)

/**
反射哭提供了内置函数make和new的对应插座，其中最有意思的就是MakeFunc。
可用它来实现通用末班，适应不同数据类型。
 */
func add(args []reflect.Value) (result []reflect.Value)  {
	if len(args) == 0 {
		return nil
	}
	var ret reflect.Value
	switch args[0].Kind() {
	case reflect.Int:
		n := 0
		for _,a := range args{
			n += int(a.Int())
		}
		ret = reflect.ValueOf(n)
	case reflect.String:
		ss := make([]string,0,len(args))
		for _,s :=range args{
			ss = append(ss,s.String())
		}
		ret = reflect.ValueOf(strings.Join(ss,""))
	}
	result = append(result,ret)
	return
}

func makeAdd(fptr interface{})  {
	fn := reflect.ValueOf(fptr).Elem()
	v := reflect.MakeFunc(fn.Type(),add)
	fn.Set(v)
}
//如果语言支持泛型就不需要这么麻烦了。。。。
func main() {
	var intAdd func(x,y int) int
	var strAdd func(a,b string) string
	makeAdd(&intAdd)
	makeAdd(&strAdd)
	println(intAdd(100,200))
	println(strAdd("hello, ","world"))
}